package com.example.administrator.leargit.extra;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.widget.ImageView;
import android.widget.ListView;

import com.example.administrator.leargit.R;
import com.example.administrator.leargit.adapter.NewAdapter;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by Administrator on 2016/12/23 0023.
 */
public class ImageLoader {
    private ListView mListView;
    private Set<NewsAsyncTask> mTask;


    private LruCache<String,Bitmap> caches;
    public ImageLoader(ListView listView){
        mListView = listView;
        mTask = new HashSet<>();

        //获得最大内存，从而设置缓存的空间大小，当款村的图骗超过设置的空间大小时
        //lru最近未被使用的图片就会被抛出缓存
        int maxMermory = (int)Runtime.getRuntime().maxMemory();
        int cacheSize = maxMermory/8;
        //匿名内部类 获得cache实例
        caches = new LruCache<String,Bitmap>(cacheSize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }
        };

    }
    public void loadImages(int start,int end){
        for(int i=start;i<end;i++){
            String url = NewAdapter.URLS[i];
            Bitmap bitmap = getBitmapFromCache(url);
            /**本来接下来应该就是看bitmap是否在缓存中，如果不在，从网络下载，否则直接设置
             * 但是，现在我们不能再用imageView，因为我们现在是作为一个整体去加载图片的
             * 加载从start到end的图片
             * 那现在怎么做呢？
             * 将mImageView改为listView ，通过findViewWithTag方法通过Tag找到在ListView 中指定的ImageView
             * 创建ListView 成员变量去存储ListView
             * 创建一个NewAsyncTask集合去集中管理每一个异步任务Task
             *
             *
             *
             *  if(bitmap==null){
             new NewsAsyncTask(mImageView,url)。execute(url);
             }else{
             mImageView.setImageBitmap(bitmap);
             }
             *
             */
            if(bitmap==null) {
                NewsAsyncTask task = new NewsAsyncTask(url);
                task.execute(url);
                mTask.add(task);
            }else{
                ImageView imageView = (ImageView) mListView.findViewWithTag(url);
                imageView.setImageBitmap(bitmap);
            }

        }

    }
    public void cancelAllTask(){
        if(mTask!=null){
            for(NewsAsyncTask task:mTask){
                task.cancel(false);
            }
        }
    }

    //先看缓存中是否有图片，没有的话就加到缓存中去
    public void addBitmapToCache(String url,Bitmap bitmap){
        if(getBitmapFromCache(url)==null){
            caches.put(url,bitmap);
        }

    }
    //根据url（key）从缓存中取出Bitmao(value)
    public Bitmap getBitmapFromCache(String url){
        return caches.get(url);
    }


    //通过一个网络url地址返回一个图片
    //得到拂去其返回的输入流
    //通过BitmapFactory的decodeStream()方法来获取图片
    public Bitmap getbitMapFromUrl(String url){
        InputStream in=null;
        Bitmap bitMap;
        URL url1 = null;

        try {
            url1 = new URL(url);
            HttpURLConnection connection= (HttpURLConnection) url1.openConnection();
            in = new BufferedInputStream(connection.getInputStream());//对InputStream进行封装
            bitMap = BitmapFactory.decodeStream(in);//根据InputStream得到BitMap
            connection.disconnect();
            return bitMap;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }



        return null;
    }

    /**
     * 接下来要把显示图片的控制权从showImageeByAsyncTask转移到loadImages
     * 方法，更改showImageeByAsyncTask的逻辑
     * 这个是原来的
     *
     *  //通过异步任务将图片设置给ImageView
     public void showImageByAsyncTask(ImageView imageView,String url){
     Bitmap bitMap = getBitmapFromCache(url);
     //如果缓存中没有图片，就从网络上下载
     //如果缓存中有图片了，直接设置
     if(bitMap==null) {
     new NewsAsyncTask(url).execute(url);
     }else{
     imageView.setImageBitmap(bitMap);
     }

     }
     *
     * 接下来我们将逻辑更改为如果缓存中没有，直接设置为默认图片即可
     */

    //如果缓存为空，直接设置默认图片，将图片从网络下载显示的控制权交给loadImages(start,end)
    public void showImageByAsyncTask(ImageView imageView,String url){
        Bitmap bitMap = getBitmapFromCache(url);

        if(bitMap==null) {
            imageView.setImageResource(R.mipmap.ic_launcher);
        }else{
            imageView.setImageBitmap(bitMap);
        }

    }
    //异步任务
    class NewsAsyncTask extends AsyncTask<String,Void,Bitmap> {
        //前期在设置ImageView和后期在避免ListView的缓存机制设置Tag时，需要用到url
        //private ImageView mImageView; 优化：有了ListView findViewWithTag将不再需要ImageView的引用
        //并且构造方法中也不再需要。之后在其他用到此构造方法的地方更改
        private String mUrl;
        public NewsAsyncTask(String url){
            // mImageView = imageView;
            mUrl = url;
        }

        //先从网络上下载图片，下载下来之后，不需要重复下载，需要加入缓存
        @Override
        protected Bitmap doInBackground(String... params) {
            String url = params[0];
            Bitmap bitmap = getbitMapFromUrl(url);
            if(bitmap!=null){
                addBitmapToCache(url,bitmap);
            }
            return  bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);

            ImageView imageView = (ImageView) mListView.findViewWithTag(mUrl);
            if(imageView!=null&&bitmap!=null){
                imageView.setImageBitmap(bitmap);
            }
            mTask.remove(this);
            /**
             * 这是之前没有对ListView做优化时的代码
             * if (mImageView.getTag().equals(mUrl)) {
             mImageView.setImageBitmap(bitmap);
             }
             *
             */

        }
    }
}
